/****************************************************************************
*  Arthea Server by R. Jennings (2007-2008)   http://arthea.googlecode.com/ *
*  By using this code you comply with the Artistic and GPLv2 Licenses.      *
****************************************************************************/


using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace Arthea.Util
{
    /// <summary>
    /// Handles serialization
    /// </summary>
    public struct Persistance
    {
        /// <summary>
        /// formats a string into a would-be file name
        /// </summary>
        /// <param name="words">the words to format</param>
        /// <returns>a possible file name</returns>
        public static string MakeFileName(string words)
        {
            return words.Replace(' ', '_').ToLower();
        }

        /// <summary>
        /// Makes sure there is a .xml extension on a filename
        /// </summary>
        /// <param name="filename">the filename to check</param>
        /// <returns>a filename that ends in .xml</returns>
        public static string XmlFileName(string filename)
        {
            if (!filename.EndsWith(".xml"))
                filename += ".xml";

            return filename;
        }

        /// <summary>
        /// Checks if an xml file of given name exits.
        /// </summary>
        /// <param name="file">the file name to check</param>
        /// <returns>true if the file exists</returns>
        public static bool XmlFileExists(string file)
        {
            return File.Exists(XmlFileName(file));
        }

        /// <summary>
        /// Deserializes (Loads) a type from a given reader
        /// </summary>
        /// <typeparam name="T">The type of object</typeparam>
        /// <param name="reader">the xml reader</param>
        /// <returns>and instance of T</returns>
        public static T Load<T>(XmlReader reader)
        {
            return (T) new XmlSerializer(typeof (T)).Deserialize(reader);
        }

        /// <summary>
        /// Deserializes an object in a file
        /// </summary>
        /// <typeparam name="T">The type of object</typeparam>
        /// <param name="filename">The filename to load</param>
        /// <returns>an instance of T</returns>
        public static T Load<T>(string filename)
        {
            XmlSerializer s = new XmlSerializer(typeof (T));
            TextReader r = new StreamReader(XmlFileName(filename));
            T data = (T) s.Deserialize(r);
            r.Close();
            return data;
        }

        /// <summary>
        /// Loads if file exists.
        /// </summary>
        /// <typeparam name="T">the type of object to load</typeparam>
        /// <param name="filename">The filename.</param>
        /// <returns>an instance of T</returns>
        public static T LoadIfExists<T>(string filename) where T : new()
        {
            if (!XmlFileExists(filename))
                return new T();

            return Load<T>(filename);
        }

        /// <summary>
        /// Saves an object to a given xml writer
        /// </summary>
        /// <param name="writer">the xml writer</param>
        /// <param name="obj">the object to save</param>
        public static void Save(XmlWriter writer, object obj)
        {
            XmlSerializer x = new XmlSerializer(obj.GetType());
            x.Serialize(writer, obj);
        }

        /// <summary>
        /// Saves the specified element name.
        /// </summary>
        /// <param name="elementName">Name of the element.</param>
        /// <param name="writer">The writer.</param>
        /// <param name="obj">The obj.</param>
        public static void Save(string elementName, XmlWriter writer, IXmlSerializable obj)
        {
            writer.WriteStartElement(elementName);
            obj.WriteXml(writer);
            writer.WriteEndElement();
        }

        /// <summary>
        /// Saves an object to a file.
        /// </summary>
        /// <param name="filename">The file name</param>
        /// <param name="obj">The object to save.</param>
        public static void Save(string filename, object obj)
        {
            XmlSerializer x = new XmlSerializer(obj.GetType());
            filename = XmlFileName(filename);
            string tempfile = Path.GetTempFileName();
            StreamWriter w = new StreamWriter(tempfile);
            x.Serialize(w, obj);
            w.Close();
            if (File.Exists(filename))
                File.Delete(filename);
            File.Move(tempfile, filename);
        }

        /// <summary>
        /// Gets a list of xml files in a specified directory
        /// </summary>
        /// <param name="path">The directory to explore</param>
        /// <returns>an array of files</returns>
        public static FileInfo[] GetDirectoryXmlFiles(string path)
        {
            return new DirectoryInfo(path).GetFiles("*.xml");
        }
    }
}